#!/usr/bin/python
# -*- coding: utf-8 -*-
# @version        : 1.0
# @Create Time: 2024/3/23 22:30
# @File: query_params.py
# @IDE: PyCharm
# @Desc: 查询参数依赖

from typing import Dict, Optional, Literal
from advanced_alchemy.filters import LimitOffset, OrderBy
from asgiref.sync import sync_to_async
from fastapi import Body, Query
import copy
from src.common.typing.common_typing import ORMModel
from src.core.query_builder import QueryBuilder


class QueryParams:
    def __init__(self, params: Optional["Paging"] = None):
        if params:
            self.page = params.page
            self.limit = params.limit
            self.order = params.order
            self.order_field = params.order_field

    def dict(self, exclude: list[str] = None) -> dict:
        result = copy.deepcopy(self.__dict__)
        if exclude:
            for item in exclude:
                try:
                    del result[item]
                except KeyError:
                    pass
        return result

    @property
    def limit_offset(self) -> LimitOffset:
        if self.limit:
            return LimitOffset(self.limit, self.limit * (self.page - 1))
        raise ValueError("没有分页参数")

    def order_by(
        self, order_field: str = None, order: Literal["asc", "desc"] = None
    ) -> OrderBy:
        """

        :param order_field: 排序字段
        :param order: 当不传入时使用self.order默认值是desc
        :return:
        """
        field_name = order_field if order_field else self.order_field
        sort_order = order if order else self.order
        if not field_name:
            raise ValueError("没有排序字段")
        return OrderBy(field_name=field_name, sort_order=sort_order)

    @sync_to_async
    def get_where_and_limit_offset(
        self, model: ORMModel, models: Dict[str, ORMModel] = None
    ):
        query = QueryBuilder(model=model, tables=models)
        where = query.build(self.to_count())
        return [*where, self.limit_offset]

    @sync_to_async
    def get_where(self, model: ORMModel, models: Dict[str, ORMModel] = None):
        query = QueryBuilder(model=model, tables=models)
        where = query.build(self.to_count())
        return [*where]

    def to_count(self, exclude: list[str] = None) -> dict:
        params = self.dict(exclude=exclude)
        del params["page"]
        del params["limit"]
        del params["order"]
        del params["order_field"]
        return params


class Paging(QueryParams):
    """
    列表分页
    """

    def __init__(
        self,
        page: int = Query(1, description="页码", ge=1, alias="current"),
        limit: int = Query(10, description="每页数量", ge=1, alias="size"),
        order_field: str = Query(None, description="排序字段"),
        order: Literal["asc", "desc"] = Query("desc", description="排序方式"),
    ):
        super().__init__()
        self.page = page
        self.limit = limit
        self.order = order
        self.order_field = order_field


class IdList:
    """
    id 列表
    """

    def __init__(self, ids: list[int] = Body(..., title="ID 列表")):
        self.ids = ids
